﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;
using DateBaseConnectionPool;

namespace TestMySqlConnetPoll
{
    public class ObjWdwSjddqx
    {
        public Int16 dotnumA;
        public Int16 dotnumB;
        public Int16 dotnumC;
        public List<ObjValue> dla = new List<ObjValue>();
        public List<ObjValue> dlb = new List<ObjValue>();
        public List<ObjValue> dlc = new List<ObjValue>();
        public List<ObjValue> dya = new List<ObjValue>();
        public List<ObjValue> dyb = new List<ObjValue>();
        public List<ObjValue> dyc = new List<ObjValue>();
    }
    public class WdwSjddTable
    {

        #region 外部函数接口， 变量定义，外电网瞬间断电        

        public struct WdwsjddThreadStruct
        {
            public string TableName;
            public AnalogCodeType codeType;
            public int  dev_no;
            public int u_time;
        }

        public int WdwSjddqxDevNo = -1;
        public List<DateTime> TimeList = new List<DateTime>();        
        public Dictionary<DateTime, ObjWdwSjddqx> ValueList = new Dictionary<DateTime, ObjWdwSjddqx>();   //时间做键值

        public bool ReadyTimeList = false;
        public bool ReadyValueList = false;
        public int ErrorFlag = 0;

        public void ReadTimeList(string DevName)
        {
            ErrorFlag = 0;
            ReadyTimeList = false;
            WdwsjddThreadStruct obj = new WdwsjddThreadStruct();
            TimeList.Clear();
            obj.TableName = "wdwsjddqx";
            obj.codeType = AnalogCodeType.None;
            obj.dev_no = c_Device.GetWdwErrorQX_DevNo(DevName);
            if (obj.dev_no >= 0)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadWdwsjddTimeList), obj);
            }
            else ErrorFlag = 1;
        }

        public void ReadValueList(string DevName,DateTime time)
        {
            ReadyValueList = false;
            ErrorFlag = 0;
            WdwsjddThreadStruct obj = new WdwsjddThreadStruct();
            obj.TableName = "wdwsjddqx";
            obj.codeType = AnalogCodeType.None;
            obj.dev_no = c_Device.GetWdwErrorQX_DevNo(DevName);
            if (obj.dev_no == WdwSjddqxDevNo && ValueList.Keys.Contains(time))
            {
                ReadyValueList = true;
                return;
            }
            if (obj.dev_no != WdwSjddqxDevNo)
            {
                WdwSjddqxDevNo = obj.dev_no;
                ValueList.Clear();
            }
            if (obj.dev_no >= 0)
            {
                obj.u_time = (int)MySql.DateTimeToTime_t(time);
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadWdwsjddValueList), obj);
            }
        }

        #endregion

        #region 外电网瞬间断电曲线

        private Mutex keyMutex = new Mutex();
        static private int keykey = 0;

        /// <summary>
        /// 外电网瞬间断电插入数据
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <param name="dotNum"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool InsertWdwsjddTable(AnalogCodeType codetype, Int16 dev_no, int u_time, Int16 dotNumA,Int16 dotNumB,Int16 dotNumC, byte[] dlA,byte[]dlB,byte[]dlC,byte[]dyA,byte[]dyB,byte[]dyC)
        {
            bool tmpFlag = false;
            string TableName = "wdwsjddqx";
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                
                if (con != null)
                {
                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0}(u_time,codetype,dev_no,dotNumA,dotNumB,dotNumC,dlA,dlB,dlC,dyA,dyB,dyC)", TableName));

                    InsertStatement.Append("values(?u_time,?codetype,?dev_no,?dotNumA,?dotNumB,?dotNumC,?dlA,?dlB,?dlC,?dyA,?dyB,?dyC)");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.Byte)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = dev_no;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumA", MySqlDbType.UInt16)).Value = dotNumA;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumB", MySqlDbType.UInt16)).Value = dotNumB;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumC", MySqlDbType.UInt16)).Value = dotNumC;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dlA", MySqlDbType.Binary)).Value = dlA.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dlB", MySqlDbType.Binary)).Value = dlB.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dlC", MySqlDbType.Binary)).Value = dlC.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dyA", MySqlDbType.Binary)).Value = dyA.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dyB", MySqlDbType.Binary)).Value = dyB.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dyC", MySqlDbType.Binary)).Value = dyC.ToArray();

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }
        /// <summary>
        /// 加入到外电网时间列表
        /// </summary>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        private void AddToWdwsjddTimeList(Int16 dev_no, int u_time)
        {            
            DateTime t = new DateTime();
            t = MySql.Time_tToDateTime(u_time);
            if (TimeList.Contains(t)) { }
            else TimeList.Add(t);
        }
        /// <summary>
        /// 读取外电网的时间列表
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <returns></returns>
        private void ThreadReadWdwsjddTimeList(object o)
        {
            WdwsjddThreadStruct obj = (WdwsjddThreadStruct)o;
            string TableName = obj.TableName;
            AnalogCodeType codetype = obj.codeType;
            Int16 dev_no = (Int16)obj.dev_no;
            
            if (TableName == "") return;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 2;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select u_time from {0} where dev_no = {1}", TableName, dev_no));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            int u_time = read.GetInt32(0);
                            AddToWdwsjddTimeList(dev_no, u_time);
                        }
                        read.Close();
                        ReadyTimeList = true;
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 3;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 4;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }
        /// <summary>
        /// 检查该设备该次的曲线是否已经在内存中
        /// </summary>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <returns></returns>
        //private bool CheckWdwsjddValueInMemory(AnalogCodeType codetype, Int16 dev_no, int u_time)
        //{
        //    if (WdwSjddqxDevNo.dev_no == dev_no || WdwSjddqxDevNo.codetype == codetype)
        //    {
        //        DateTime d_time = MySql.Time_tToDateTime(u_time);
        //        if (WdwsjddValueList.ContainsKey(d_time)) return true;
        //    }
        //    return false;
        //}
        /// <summary>
        /// 把从数据库中读到的值加入到缓冲区内
        /// </summary>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <param name="dot"></param>
        /// <param name="value"></param>
        private void AddToWdwsjddValueList(AnalogCodeType codetype, Int16 dev_no, int u_time, short dotA,short dotB,short dotC, byte[] dla,byte[]dlb,byte[]dlc,byte[]dya,byte[]dyb,byte[]dyc)
        {              
            ObjWdwSjddqx tmp = new ObjWdwSjddqx();
            tmp.dotnumA = dotA;
            tmp.dotnumB = dotB;
            tmp.dotnumC = dotC;
            string AnalogName = c_Device.GetAnalogTypeName(codetype);
            int m = 0;
            for (int i = 0; i < dotA; i++)
            {
                int low = dla[m];
                int hig = dla[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dla.Add(t);
            }
            m = 0;
            for (int i = 0; i < dotB; i++)
            {
                int low = dlb[m];
                int hig = dlb[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dlb.Add(t);
            }
            m = 0;
            for (int i = 0; i < dotC; i++)
            {
                int low = dlc[m];
                int hig = dlc[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dlc.Add(t);
            }
            m = 0;
            for (int i = 0; i < dotA; i++)
            {
                int low = dya[m];
                int hig = dya[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dya.Add(t);
            }
            m = 0;
            for (int i = 0; i < dotB; i++)
            {
                int low = dyb[m];
                int hig = dyb[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dyb.Add(t);
            }
            m = 0;
            for (int i = 0; i < dotC; i++)
            {
                int low = dyc[m];
                int hig = dyc[m + 1];
                m += 2;
                int value = hig * 256 + low;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (Int16)value);
                tmp.dyc.Add(t);
            }
            DateTime d_time = MySql.Time_tToDateTime(u_time);
            ValueList.Add(d_time, tmp);
        }
        /// <summary>
        /// 从数据库中读取值到换场去内
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <returns></returns>
        private void ThreadReadWdwsjddValueList(object o)
        {
            WdwsjddThreadStruct obj = (WdwsjddThreadStruct)o;
            string TableName = obj.TableName;
                 AnalogCodeType codetype = obj.codeType;
                      Int16 dev_no = (Int16)obj.dev_no;
                      int u_time = obj.u_time;
                       

            if (TableName == "") return;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 1;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select dotNumA,dotNumB,dotNumC,dlA,dlB,dlC,dyA,dyB,dyC from {0} where dev_no = {1} and u_time = {2}", TableName, dev_no, u_time));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            short lenA = read.GetInt16(read.GetOrdinal("dotNumA"));
                            short lenB = read.GetInt16(read.GetOrdinal("dotNumB"));
                            short lenC = read.GetInt16(read.GetOrdinal("dotNumC"));
                            byte[] dla = new byte[200];
                            read.GetBytes(read.GetOrdinal("dlA"), 0, dla, 0, lenA*2);
                            byte[] dlb = new byte[200];
                            read.GetBytes(read.GetOrdinal("dlB"), 0, dlb, 0, lenB*2);
                            byte[] dlc = new byte[200];
                            read.GetBytes(read.GetOrdinal("dlC"), 0, dlc, 0, lenC*2);

                            byte[] dya = new byte[200];
                            read.GetBytes(read.GetOrdinal("dyA"), 0, dya, 0, lenA*2);
                            byte[] dyb = new byte[200];
                            read.GetBytes(read.GetOrdinal("dyB"), 0, dyb, 0, lenB*2);
                            byte[] dyc = new byte[200];
                            read.GetBytes(read.GetOrdinal("dyC"), 0, dyc, 0, lenC*2);

                            AddToWdwsjddValueList(codetype, dev_no, u_time, lenA, lenB, lenC, dla, dlb, dlc, dya, dyb, dyc);
                        }
                        read.Close();
                        ReadyValueList = true;
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 4;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 5;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }
        #endregion
    }
}
